﻿using LinkPad.Helpers;
using LinkPad.Shapes;
using Windows.Devices.Input;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Input.Inking;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;

namespace LinkPad.Handlers
{
    class InkPenDrawer : CanvasActionHandler
    {
        #region Fields

        readonly InkManager _inkKhaled = new InkManager();
        private uint _penId;
        private uint _touchId;
        private Point _previousContactPt;
        private Color _penColor = ManagedLine.DefaultStrokeColor;

        #endregion

        #region Constructors

        public InkPenDrawer(ShapeManager shapeManager)
            : base(shapeManager)
        {
        }

        #endregion

        #region Properties

        public override Color MainColor
        {
            get
            {
                return _penColor;
            }
            set
            {
                _penColor = value;
            }
        }

        #endregion

        #region Methods

        protected override void HandlePointerPressed(object sender, PointerRoutedEventArgs e)
        {
            // Get information about the pointer location.
            var pt = e.GetCurrentPoint(MyCanvas);
            _previousContactPt = pt.Position;

            // Accept input only from a pen or mouse with the left button pressed. 
            var pointerDevType = e.Pointer.PointerDeviceType;
            if (pointerDevType == PointerDeviceType.Pen ||
                    pointerDevType == PointerDeviceType.Mouse &&
                    pt.Properties.IsLeftButtonPressed)
            {
                // Pass the pointer information to the InkManager.
                _inkKhaled.ProcessPointerDown(pt);
                _penId = pt.PointerId;

                e.Handled = true;
            }
            else if (pointerDevType == PointerDeviceType.Touch)
            {
                // TODO touch not supported 
            }

            base.HandlePointerPressed(sender, e);
        }

        protected override void HandlePointerMoved(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerId == _penId)
            {
                var pt = e.GetCurrentPoint(MyCanvas);

                // Render a red line on the canvas as the pointer moves. 
                // Distance() is an application-defined function that tests
                // whether the pointer has moved far enough to justify 
                // drawing a new line.
                var currentContactPt = pt.Position;
                var x1 = _previousContactPt.X;
                var y1 = _previousContactPt.Y;
                var x2 = currentContactPt.X;
                var y2 = currentContactPt.Y;

                if (GeometryHelper.Distance(x1, y1, x2, y2) > 2.0) // We need to developp this method now 
                {
                    var line = new ManagedLine(ShapeManager)
                    {
                        X1 = x1,
                        Y1 = y1,
                        X2 = x2,
                        Y2 = y2,
                        Stroke = new SolidColorBrush(_penColor)
                    };

                    _previousContactPt = currentContactPt;

                    // Draw the line on the canvas by adding the Line object as
                    // a child of the Canvas object.

                    ShapeManager.AddShape(line);

                    // Pass the pointer information to the InkManager.
                    _inkKhaled.ProcessPointerUpdate(pt);
                }
            }
            else if (e.Pointer.PointerId == _touchId)
            {
                // Process touch input
            }

            base.HandlePointerMoved(sender, e);
        }

        protected override void HandlePointerReleased(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerId == _penId)
            {
                var pt = e.GetCurrentPoint(MyCanvas);

                // Pass the pointer information to the InkManager. 
                _inkKhaled.ProcessPointerUp(pt);
            }
            else if (e.Pointer.PointerId == _touchId)
            {
                // Process touch input
            }

            _touchId = 0;
            _penId = 0;

            // Call an application-defined function to render the ink strokes.

            e.Handled = true;
        }

        protected override void HandlePointerExited(object sender, PointerRoutedEventArgs e)
        {
            HandlePointerReleased(sender, e);
        }

        #endregion
    }
}
